package com.th.supcom.pds.impl.service.internal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.carefx.framework.exception.BusinessException;
import net.carefx.framework.translate.TranslatorManager;
import net.carefx.framework.util.ConvertUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import com.th.supcom.pds.domain.pojo.PdsSupply;
import com.th.supcom.pds.domain.pojo.PdsSupplyDetail;
import com.th.supcom.pds.domain.pojo.PdsSupplyPro;
import com.th.supcom.pds.domain.vo.PatientInfo;
import com.th.supcom.pds.domain.vo.PdsSupplyDetailVO;
import com.th.supcom.pds.domain.vo.PdsSupplyProVO;
import com.th.supcom.pds.domain.vo.PdsSupplyResultSet;
import com.th.supcom.pds.domain.vo.PdsSupplyVO;
import com.th.supcom.pds.impl.common.enums.SendOrReturnEnum;
import com.th.supcom.pds.impl.common.utils.ServerUitls;
import com.th.supcom.pds.impl.manager.PdsSupplyDetailManager;
import com.th.supcom.pds.impl.manager.PdsSupplyManager;
import com.th.supcom.pds.impl.manager.PdsSupplyProManager;
import com.th.supcom.pds.internal.api.SupplyStatusQueryService;
import com.th.supcom.pds.medicare.api.AdapterEmrPrescriptionService;
import com.th.supcom.pds.medicare.api.AdapterPtsExtOutPatientVisitService;

public class SupplyStatusQueryServiceImpl implements SupplyStatusQueryService
{
    /** 翻译器 */
    private TranslatorManager m_translatorManager;
    private PdsSupplyManager m_pdsSupplyManager;
    private PdsSupplyDetailManager m_pdsSupplyDetailManager;
    private PdsSupplyProManager m_pdsSupplyProManager;
    private AdapterPtsExtOutPatientVisitService m_adapterPtsExtOutPatientVisitService;
    private AdapterEmrPrescriptionService m_adapterEmrPrescriptionService;
    /** 日志记录器. */
    public static final Logger s_logger = LoggerFactory.getLogger (SupplyStatusQueryServiceImpl.class);

    @Override
    public List <PdsSupplyResultSet> findSupplyStatusByCondition (Map <String, Object> map)
    {
        s_logger.debug ("进入findSupplyStatusByCondition方法,入参:prescNo:{},rcptNo:{}", new Object[]
        { map.get ("prescNo"), map.get ("rcptNo") });
        if (map.get ("prescNo") == null && map.get ("rcptNo") == null)
        {
            throw new BusinessException ("参数异常！处方号或收据号不能同时为空！");
        }
        List <PdsSupplyResultSet> pdsSupplyResultSets = new ArrayList <PdsSupplyResultSet> ();
        List <PdsSupply> pdsSupplies = getSupplyInfo (map);
        if (CollectionUtils.isEmpty (pdsSupplies) && map.get ("prescNo") != null)
        {
            return findPrescInfoFromCPOE (map, pdsSupplyResultSets);
        }
        if (CollectionUtils.isEmpty (pdsSupplies))
        {
            s_logger.error ("根据条件没有找到相关记录");
            throw new BusinessException ("没有找到相关记录，请检查输入是否正确！");
        }
        getSupplyDetailsAndSupplyPro (pdsSupplyResultSets, pdsSupplies);
        PatientInfo patientInfo = getPatientInfo (pdsSupplies.get (0).getPatientId (), pdsSupplyResultSets.get (0).getPdsSupplyVO ().getPrescSource ());
        pdsSupplyResultSets.get (0).setPatientInfo (patientInfo);

        return pdsSupplyResultSets;
    }

    private List <PdsSupplyResultSet> findPrescInfoFromCPOE (Map <String, Object> map, List <PdsSupplyResultSet> pdsSupplyResultSets)
    {
        Map <String, Object> cpoeMap = new HashMap <String, Object> ();
        cpoeMap.put ("prescNo", map.get ("prescNo"));
        cpoeMap.put ("type", "1");
        List <PdsSupplyVO> pdsSupplyVOs = null;
        try
        {
            pdsSupplyVOs = m_adapterEmrPrescriptionService.findApplyAndPresc (cpoeMap);
        }
        catch (Exception e)
        {
            s_logger.error ("查询CPOE处方信息失败！入参:prescNo:{},rcptNo:{}", new Object[]
            { map.get ("prescNo"), map.get ("rcptNo"), e });
            throw new BusinessException ("查询处方信息出现异常！请联系计算机中心！", e);
        }
        if (CollectionUtils.isEmpty (pdsSupplyVOs))
        {
            s_logger.error ("根据条件没有找到相关记录!入参:prescNo:{},rcptNo:{}", new Object[]
            { map.get ("prescNo"), map.get ("rcptNo") });
            throw new BusinessException ("没有找到相关记录，请检查输入是否正确！");
        }
        PdsSupplyVO pdsSupplyVO = pdsSupplyVOs.get (0);
        Map <String, Object> cpoeDetailMap = new HashMap <String, Object> ();
        cpoeDetailMap.put ("id", pdsSupplyVO.getPrescId ());
        cpoeDetailMap.put ("type", "1");
        cpoeDetailMap.put ("prescNo", pdsSupplyVO.getPrescNo ());
        List <PdsSupplyDetailVO> pdsSupplyDetailVOs = null;
        try
        {
            pdsSupplyDetailVOs = m_translatorManager.translate (m_adapterEmrPrescriptionService.findApplyAndDetailed (cpoeDetailMap));
        }
        catch (Exception e)
        {
            s_logger.error ("查询CPOE处方信息失败！入参:prescNo:{},rcptNo:{}", new Object[]
            { map.get ("prescNo"), map.get ("rcptNo") });
            throw new BusinessException ("查询处方信息出现异常！请联系计算机中心！");
        }
        pdsSupplyVO.setCheckFlag (ServerUitls.checkPhamsToxicology (pdsSupplyDetailVOs));
        ServerUitls.findPhamsCosts (pdsSupplyDetailVOs);
        PatientInfo patientInfo = getPatientInfo (pdsSupplyVO.getPatientId (), pdsSupplyVO.getPrescSource ());
        PdsSupplyProVO pdsSupplyProVO = new PdsSupplyProVO ();
        PdsSupplyResultSet pdsSupplyResultSet = new PdsSupplyResultSet ();
        pdsSupplyResultSet.setPdsSupplyVO (pdsSupplyVO);
        pdsSupplyResultSet.setPdsSupplyDetailVOs (pdsSupplyDetailVOs);
        pdsSupplyResultSet.setPdsSupplyProVO (pdsSupplyProVO);
        pdsSupplyResultSet.setPatientInfo (patientInfo);
        pdsSupplyResultSets.add (pdsSupplyResultSet);
        return pdsSupplyResultSets;
    }

    /**
     * 查询供药明细记录和供药过程记录
     * 
     * @param pdsSupplyResultSets
     * @param pdsSupplies
     */
    private void getSupplyDetailsAndSupplyPro (List <PdsSupplyResultSet> pdsSupplyResultSets, List <PdsSupply> pdsSupplies)
    {
        for (PdsSupply pdsSupply : pdsSupplies)
        {
            PdsSupplyResultSet pdsSupplyResultSet = new PdsSupplyResultSet ();
            PdsSupplyVO pdsSupplyVO = ConvertUtils.convert (PdsSupplyVO.class, pdsSupply);
            pdsSupplyVO = m_translatorManager.translate (pdsSupplyVO);
            pdsSupplyResultSet.setPdsSupplyVO (pdsSupplyVO);
            Map <String, Object> proMap = new HashMap <String, Object> ();
            proMap.put ("supplyId", pdsSupply.getSupplyId ());
            List <PdsSupplyPro> pdsSupplyPros = m_pdsSupplyProManager.findPdsSupplyProListByMap (proMap);
            if (CollectionUtils.isEmpty (pdsSupplyPros) || pdsSupplyPros.size () > 1)
            {
                s_logger.error ("数据异常！没有查询到相应供药过程记录或存在多条供药记录!");
                throw new BusinessException ("数据异常！没有查询到相应供药过程记录或存在多条供药记录!");
            }
            PdsSupplyPro pdsSupplyPro = m_translatorManager.translate (pdsSupplyPros.get (0));
            PdsSupplyProVO pdsSupplyProVO = ConvertUtils.convert (PdsSupplyProVO.class, pdsSupplyPro);
            Map <String, Object> detailMap = new HashMap <String, Object> ();
            detailMap.put ("supplyId", pdsSupply.getSupplyId ());
            List <PdsSupplyDetail> pdsSupplyDetails = m_pdsSupplyDetailManager.findPdsSupplyDetailListByMap (detailMap);
            if (CollectionUtils.isEmpty (pdsSupplyDetails))
            {
                s_logger.error ("数据异常，没有查询到相关的供药明细记录！");
                throw new BusinessException ("数据异常，没有查询到相关的供药明细记录！");
            }
            List <PdsSupplyDetailVO> pdsSupplyDetailVOs = ConvertUtils.convert (PdsSupplyDetailVO.class, pdsSupplyDetails);
            pdsSupplyDetailVOs = m_translatorManager.translate (pdsSupplyDetailVOs);
            pdsSupplyResultSet.setPdsSupplyVO (pdsSupplyVO);
            pdsSupplyResultSet.setPdsSupplyDetailVOs (pdsSupplyDetailVOs);
            pdsSupplyResultSet.setPdsSupplyProVO (pdsSupplyProVO);
            pdsSupplyResultSets.add (pdsSupplyResultSet);
        }
    }

    /**
     * 查询患者Id
     * 
     * @param pdsSupplies
     * @return
     */
    private PatientInfo getPatientInfo (String patientId, Integer prescSource)
    {
        if (patientId == null)
        {
            throw new BusinessException ("数据异常！记录中患者ID为空！");
        }
        PatientInfo patientInfo;
        try
        {
            patientInfo = m_adapterPtsExtOutPatientVisitService.getPatientInfo (null, prescSource, patientId);
        }
        catch (Exception e1)
        {
            s_logger.error ("调用患者查询服务接口出现异常！异常信息：", new Object[]
            { e1 });
            throw new BusinessException ("调用患者信息查询服务出现异常！" + e1.getMessage ());
        }
        if (patientInfo == null)
        {
            s_logger.error ("找不到患者相关信息！请检查参数是否正确！");
            throw new BusinessException ("找不到患者相关信息！请检查参数是否正确！");
        }
        return patientInfo;
    }

    private List <PdsSupply> getSupplyInfo (Map <String, Object> map)
    {
        List <PdsSupply> pdsSupplies;
        map.put ("sendOrReturnFlag", SendOrReturnEnum.Send.getCode ());
        try
        {
            pdsSupplies = m_pdsSupplyManager.findPdsSupplyListByMap (map);
        }
        catch (Exception e)
        {
            s_logger.error ("查询供药记录出现异常，异常信息：", new Object[]
            { e });
            throw new BusinessException ("查询供药记录出现异常，请联系计算机中心！" + e.getMessage (), e);
        }
        return pdsSupplies;
    }

    public void setTranslatorManager (TranslatorManager translatorManager)
    {
        m_translatorManager = translatorManager;
    }

    public void setPdsSupplyManager (PdsSupplyManager pdsSupplyManager)
    {
        m_pdsSupplyManager = pdsSupplyManager;
    }

    public void setPdsSupplyDetailManager (PdsSupplyDetailManager pdsSupplyDetailManager)
    {
        m_pdsSupplyDetailManager = pdsSupplyDetailManager;
    }

    public void setPdsSupplyProManager (PdsSupplyProManager pdsSupplyProManager)
    {
        m_pdsSupplyProManager = pdsSupplyProManager;
    }

    public void setAdapterPtsExtOutPatientVisitService (AdapterPtsExtOutPatientVisitService adapterPtsExtOutPatientVisitService)
    {
        m_adapterPtsExtOutPatientVisitService = adapterPtsExtOutPatientVisitService;
    }

    /**
     * @param adapterEmrPrescriptionService the adapterEmrPrescriptionService to
     *            set.
     */
    public void setAdapterEmrPrescriptionService (AdapterEmrPrescriptionService adapterEmrPrescriptionService)
    {
        m_adapterEmrPrescriptionService = adapterEmrPrescriptionService;
    }

}
